home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / uupc30sr.cpt / Files in common / pcmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-11  |  23.8 KB  |  1,013 lines

  1.  
  2. /*         pcmail.c
  3.  
  4.  
  5.  
  6.         copyright (C) 1987 Stuart Lynne
  7.  
  8.         Copying and use of this program are controlled by the terms of the
  9.         Free Software Foundations GNU Emacs General Public License.
  10.  
  11.             Portions Copyright ⌐ David Platt, 1992, 1991.  All Rights Reserved
  12.             Worldwide.
  13.  
  14.  
  15.         version        0.1        March 31/1987
  16.  
  17.  
  18. pcmail
  19.  
  20.         pcmail address1 address2 ... < the.message
  21.  
  22. description
  23.  
  24.     An 822 compatible (hopefully) mail delivery system for pc's.
  25.  
  26.     Designed for delivering mail on a pc based system. It will put
  27.     local mail (ie, not @ or ! in address) into files in the default
  28.     mail directory.
  29.  
  30.     If remote it will put into an outgoing mailbag in the default mail
  31.     directory. Performs a simple bundling of mail messages into one
  32.     file with arguments prepended as To: arg header lines. And adds a
  33.     Message-Lines: header which gives the number of lines in the
  34.     content part of the message (after the first blank line).
  35.  
  36.         pcmail john jack jill@xyz.uucp < afile
  37.  
  38.         To: john
  39.         To: jack
  40.         To: jill@xyz.uucp
  41.         X-Message-Lines: ?????
  42.         Content-Length: ?????
  43.  
  44.         ...
  45.         ...
  46.         ...
  47.  
  48.     Content-Length: is used without X- prepended to be compatible with AT&T
  49.     Mail bundles. This is not 822 compatible per se, but is allowed.
  50.  
  51.     It also adds the from From and Date lines. Subject: lines may be inserted
  52.     by placing them at the beginning of the message.
  53.  
  54.     A Unix version should lock the /usr/mail/mailbag file.
  55.  
  56.     Another program called rpcmail will unbundle the files created by
  57.     pcmail and deliver each message to the local rmail. So conceptually
  58.  
  59.         (pcmail ..... < ...; pcmail .... < ...) | sz -> rz | rpcmail
  60.  
  61.     would deliver remote messages intact.
  62.  
  63. environment variables
  64.  
  65.     The following evironment variables are used:
  66.  
  67.         MAILBOX        current user's mailbox,     "stuart"
  68.         NAME        current user's name,         "Stuart Lynne"
  69.         DOMAIN        domain of this machine,     "slynne.mac.van-bc.can"
  70.         MAILDIR        where is mail kept,            "mpw:mail"
  71.         ALIAS        user's mail aliases            ".alias"
  72.  
  73. compiling
  74.  
  75.     Compiled by itself it will operate as a standalone program. If the
  76.     compiler option:
  77.  
  78.         -DNOMAIN
  79.  
  80.     is used, it will compile as a routine:
  81.  
  82.         pcmail (argc, argv)
  83.         char **argv;
  84.         int argc;
  85.  
  86.     and can be used internally in other programs.
  87.  
  88.  
  89. Customization
  90.  
  91.     PCMAIL        mailbag for remote mail
  92.     FAKEUUX        emulate uux, make appropriate files in SPOOLDIR
  93.  
  94.     RMAIL        rmail
  95.  
  96.     DEBUG1        first level Debug trace
  97.  
  98.  
  99. */
  100.  
  101. /*
  102.     Load in the #define directives which identify this incarnation of pcmail.c as either
  103.     an inbound mailer (rmail) or as a local mail-agent (lmail).
  104. */
  105.  
  106. #include "pcmail.h"
  107.  
  108. #include <stdio.h>
  109. #ifdef     THINK_C
  110. #include <unix.h>
  111. #endif
  112. #include "host.h"
  113. #include "ndir.h"
  114. /*
  115. #endif
  116. */
  117.  
  118. FILE *FOPEN();
  119.  
  120. #define FORWARD        "Forward to"
  121.  
  122.  
  123. #define    SBUFSIZ        124
  124. #define RMAILCMDSIZ        120
  125.  
  126.  
  127. FILE   *mailfile;
  128. #ifdef Upgrade
  129. FILE   *aliasfile;
  130. #endif Upgrade
  131. FILE   *tempfile;
  132.  
  133. char    buf[BUFSIZ];
  134. char    miscbuff[255];
  135. long int lines = 0;
  136. long int bytes = 0;
  137. long int sequence = 0;
  138.  
  139. time_t tloc;
  140. char chartime[128];    /* current time in characters */
  141. char *thetime;
  142.  
  143. char    tfilename[255];
  144. char    mfilename[255];
  145. char    mailsent[255];
  146.  
  147. #ifdef Upgrade
  148. char    afilename[255];
  149. #endif Upgrade
  150.  
  151. int local = TRUE;
  152.  
  153. char viaremote[BUFSIZ] = "";
  154. char thisremote[BUFSIZ] = "";
  155.  
  156. char     remotes[BUFSIZ];
  157.  
  158. char gotitfrom[BUFSIZ] = "";
  159. char gotfromuser[BUFSIZ] = "";
  160.  
  161.  
  162. char uucp[] = "uucp";
  163.  
  164. char *fgets();
  165. int fputs();
  166.  
  167. #ifdef NOMAIN
  168.  
  169. #ifdef RMAIL
  170. #define main    rmail
  171. #else
  172. #define    main    lmail
  173. #endif
  174.  
  175. #define exit    return
  176.  
  177. extern int debuglevel;
  178.  
  179. #else
  180. int debuglevel;
  181. #endif
  182.  
  183. #ifndef RMAIL
  184. char    Subject[132] = "";
  185. #endif
  186.  
  187. char *mcurdir;
  188. char s_mcurdir[128];    /* current directory path (save malloc call) */
  189. char * getcwd();
  190. int chdir();
  191.  
  192. #ifdef MULTIFINDER
  193. #define UnImplTrapNum 0x9F
  194. #define StripAddressTrapNum 0x55
  195. long int Strip(long int);
  196. long int Strip(long int foo)
  197. {
  198.     if (NGetTrapAddress( StripAddressTrapNum,OSTrap) !=
  199.          NGetTrapAddress(UnImplTrapNum,ToolTrap)) {
  200.         return (long int) StripAddress(foo);
  201.     } else {
  202.         return (Lo3Bytes & (long int) foo);
  203.      }
  204. }    
  205. #endif
  206.  
  207. int
  208. sendit(argc, argv, addr, remotes)
  209.     char **argv, *addr, *remotes; {
  210.     int s1, s2;
  211.     int err = 1;
  212.     char routelist[BUFSIZ], tryroute[BUFSIZ];
  213.     
  214.     char *bang, *atsign, *percent;
  215.  
  216. /*
  217.     Recognize and strip off our own nodename and domain name, whether by l@nd, s%, or sk!
  218. */
  219.  
  220. #ifdef NOTDEF
  221.     fprintf(stderr, "Address %s, node %s, domain %s\n", addr, nodename, domain);
  222.     fflush(stderr);
  223. #endif
  224.     
  225.     atsign = strrchr(addr, '@');
  226.     
  227.     while (atsign != NULL && IUMagIDString(domain, atsign+1, strlen(domain), strlen(atsign+1)) == 0) {
  228.         *atsign = '\0';
  229.         atsign = strrchr(addr, '@');
  230.     }
  231.     
  232.     bang = strchr(addr, '!');
  233.  
  234.     while (bang != NULL && (IUMagIDString(nodename, addr, strlen(nodename), bang-addr) == 0 ||
  235.                                    IUMagIDString(domain, addr, strlen(domain), bang-addr) == 0)) {
  236. #ifdef NOTDEF
  237.             SysBeep(1);
  238. #endif
  239.         addr = bang+1;
  240.         bang = strchr(addr, '!');
  241.     }
  242.     
  243.     percent = strrchr(addr, '%');
  244.     
  245.     while (percent != NULL && IUMagIDString(domain, percent+1, strlen(domain), strlen(percent+1)) == 0) {
  246.         *percent = '\0';
  247.         percent = strrchr(addr, '%');
  248.     }
  249.     
  250.     
  251.     if(atsign || bang || percent) {
  252.         if ( debuglevel > 5 )
  253.             fprintf( stderr, "pcmail: send to remote\n" );
  254.         
  255.         if (atsign || percent) {
  256.             strcpy(thisremote, mailserv);
  257.         } else {
  258.             strncpy(thisremote, addr, bang - addr);
  259.             thisremote[bang - addr] = '\0';
  260.             sprintf(routelist, ",%s,", routevia);
  261.             sprintf(tryroute, ",%s,", thisremote);
  262.             if (strstr(routelist, tryroute) == NULL) {
  263.                 strcpy(thisremote, mailserv);
  264.             }
  265.         }
  266.  
  267.         s1 = strlen(remotes);
  268.         s2 = strlen(addr);
  269.  
  270.         /* can we cram one more address on line?  same host? */
  271.         if( s1 > 0 && ((s1 + s2 + 1) > RMAILCMDSIZ || strcmp(thisremote, viaremote) != 0)) {
  272.             /* dump it then, too bad */
  273.             err &= sendone(argc, argv, remotes, TRUE);
  274.             remotes[0] = '\0';
  275.             GetSequenceNumber(); /* update seq # for new sending */
  276.         }
  277.  
  278.         /* add *argvec to list of remotes */
  279.         strcat(remotes, " ");
  280.         strcat(remotes, addr);
  281.         strcpy(viaremote, thisremote);
  282.     }
  283.     else {
  284.         if (debuglevel > 5)
  285.             fprintf(stderr, "pcmail: calling sendone %s\n", addr);
  286.         err &= sendone(argc, argv, addr, FALSE);
  287.     }
  288.     return (err);
  289. }
  290.  
  291. main(argc, argv)
  292.     char **argv; {
  293.     long int position;
  294.     register int header = 1;
  295.     register int amount;
  296.  
  297.     register int argcount;
  298.     register char **argvec;
  299.     int remote;
  300.     int err = 1;
  301.     DIR    *spoolDir;
  302. #ifdef Upgrade
  303.     int gotalias;
  304. #endif Upgrade
  305.  
  306. #ifndef NOMAIN
  307.     /* get environment var's */
  308.     err = 1;
  309.     HOSTINIT;
  310.     loadenv();
  311.  
  312.      if (argc <= 1) {
  313.         fprintf( stderr, "pcmail usage: pcmail addresses < message\n" );
  314.         exit(1);
  315.     }
  316.     debuglevel = 1;
  317.  
  318. #endif
  319. #ifdef RMAIL
  320.     local = FALSE;
  321. #else
  322.     local = TRUE;
  323. #endif
  324.  
  325.     if ( debuglevel > 5 ) {
  326.         fprintf( stderr, "pcmail: argc %d ", argc );
  327.         argcount = argc;
  328.         argvec = argv;
  329.         while (argcount--) {
  330.             fprintf( stderr, " \"%s\"", *argvec++ );
  331.             }
  332.         fprintf( stderr, "\n" );
  333.  
  334.         tloc = time((time_t *)NULL );
  335.         thetime = ctime(&tloc);
  336.         fprintf( stderr, "thetime: %s\n",thetime );
  337.     }
  338.  
  339. #ifdef MSDOS
  340.      mcurdir = getcwd( s_mcurdir, sizeof(s_mcurdir) );
  341. #else
  342.     mcurdir = getcwd( s_mcurdir, sizeof(s_mcurdir) );
  343. #endif
  344.     chdir( spooldir );
  345.     /*
  346.     spoolDir = opendir (spooldir);
  347.     */
  348.     
  349.     GetSequenceNumber();
  350.  
  351.     /* open a temporary file */
  352.     /* sprintf( tfilename, TFILENAME, sequence ); */
  353.      sprintf( tfilename, TFILENAME, sequence );
  354.      mkfilename( miscbuff, tempdir, tfilename );
  355.      if (*tempdir != SEPCHAR)
  356.          mkfilename(tfilename, mcurdir, miscbuff);
  357.      else strcpy(tfilename, miscbuff);
  358.  
  359.      if ( debuglevel > 5 )
  360.          fprintf( stderr, "pcmail: opening %s\n", tfilename );
  361.  
  362.     tempfile = FOPEN( tfilename, "w", 't' );
  363.      if (tempfile == (FILE *)NULL)  {
  364.         fprintf( stderr, "pcmail: can't open %s\n", tfilename );
  365.         exit(1);
  366.     }
  367.  
  368.     /* copy stdin to tempfile, counting content lines and bytes */
  369.     header = 1;
  370.     while (fgets( buf, 512, stdin ) != (char *)NULL) {
  371.         if (header != 0) {
  372.             if (strlen( buf ) == 1) {
  373.                 header = 0;
  374.                 fprintf( tempfile, "\n" );
  375.                 continue;
  376.             }
  377.             /*
  378.             else if (strchr( buf, ':' ) == NULL) {
  379.                 header = 0;
  380.                 fprintf( tempfile, "\n" );
  381.             }
  382.             */
  383.         }
  384.         if (header == 0) {
  385.             lines++;
  386.             bytes += strlen( buf );
  387.         }
  388.         fputs( buf, tempfile );
  389. #ifdef MULTIFINDER
  390.         Check_Events(0);
  391. #endif
  392.     }
  393. #ifndef RMAIL
  394.     /* copy stdin to tempfile, counting content lines and bytes */
  395.     /* get signature */
  396.     mkfilename( miscbuff, home, signature );
  397.     if (*home != SEPCHAR)
  398.          mkfilename(mfilename, mcurdir, miscbuff);
  399.      else strcpy(mfilename, miscbuff);
  400.  
  401.     if (debuglevel > 4)
  402.         fprintf( stderr, "pcmail: opening sigfile %s\n", mfilename );
  403.     mailfile = FOPEN( mfilename, "r", 't' );
  404.     if (mailfile != (FILE *)NULL) {
  405.         fputs( "\n--\n", tempfile );
  406.         while (fgets( buf, 512, mailfile ) != (char *)NULL) {
  407.             lines++;
  408.             bytes += strlen( buf );
  409.             fputs( buf, tempfile );
  410.         }
  411.         fclose( mailfile );
  412.      }
  413. #endif
  414.  
  415.      fclose( tempfile );
  416.  
  417.     if ( debuglevel > 4 ) {
  418.         fprintf( stderr, "pcmail: stdin copied to tmp %ld %ld\n",
  419.                      bytes, lines );
  420.          fprintf( stderr, "pcmail: args %d\n", argc );
  421.     }
  422.  
  423.     /* loop on args, copying to appropriate postbox,
  424.        do remote only once
  425.        remote checking is done empirically, could be better
  426.     */
  427.     remotes[0] = '\0';
  428.  
  429.  
  430. #ifndef RMAIL
  431.     if ( strcmp( argv[1], "-s" ) == SAME ) {
  432.         argv++;argv++;
  433.         argc--;argc--;
  434.         if ( argc == 0 )
  435.             return( -1 );
  436.         strcpy( Subject, *argv );
  437.         }
  438. #endif
  439.     argcount = argc;
  440.     argvec = argv;
  441.  
  442.     while (--argcount > 0) {
  443.         argvec++;
  444.         if ( debuglevel > 5 )
  445.             fprintf( stderr, "pcmail: arg# %d\ %s\n",
  446.                             argcount, *argvec );
  447. #ifdef Upgrade    
  448.         /* get alias file */
  449.         mkfilename(miscbuff, home, alias);
  450.         if(*home != SEPCHAR)
  451.              mkfilename(afilename, mcurdir, miscbuff);
  452.          else
  453.              strcpy(afilename, miscbuff);
  454.  
  455.         if(debuglevel > 4)
  456.             fprintf(stderr, "pcmail: opening alias file %s\n", afilename);
  457.         gotalias = FALSE;
  458.         if((aliasfile=FOPEN(afilename, "r", 't')) != (FILE *)NULL) {
  459.             char str[256], *args[255];
  460.             int i, nargs;
  461.             char *theAlias, *newAlias;
  462. #ifdef MULTIFINDER
  463.             Handle aliasHandle;
  464.             aliasHandle = NULL;
  465. #endif
  466.             theAlias = (char *) NULL;
  467.  
  468.             while(fgets(str, 255, aliasfile) != (char *)NULL && !feof(aliasfile)) {
  469. #ifdef MULTIFINDER
  470.                 aliasHandle = NewHandle(strlen(str)+1);
  471.                 if (aliasHandle) {
  472.                     MoveHHi(aliasHandle);
  473.                     HLock(aliasHandle);
  474.                     theAlias = (char *) Strip((long int) *aliasHandle);
  475.                 } else {
  476.                     theAlias = (char *) NULL;
  477.                 }
  478. #else
  479.                 theAlias = malloc(strlen(str) + 1);
  480. #endif
  481.                 if (theAlias == (char *) NULL) {
  482.                     fprintf(stderr, "Can't get string buffer for alias!");
  483.                     break;
  484.                 }
  485.                 strcpy(theAlias, str);
  486.                 while(strlen(theAlias) > 0 && theAlias[strlen(theAlias)-1] <= ' ') {
  487.                     theAlias[strlen(theAlias)-1] = '\0';
  488.                 }
  489.                 while (theAlias[strlen(theAlias)-1] == '\\') {
  490.                     theAlias[strlen(theAlias)-1] = ' ';
  491.                     if (fgets(str, 255, aliasfile) != (char *)NULL && !feof(aliasfile)) {
  492. #ifdef MULTIFINDER
  493.                         HUnlock(aliasHandle);
  494.                         SetHandleSize(aliasHandle, strlen(theAlias) + strlen(str) + 1);
  495.                         if (MemError() == noErr) {
  496.                             MoveHHi(aliasHandle);
  497.                             HLock(aliasHandle);
  498.                             newAlias = (char *) Strip((long int) *aliasHandle);
  499.                         } else {
  500.                             newAlias = (char *) NULL;
  501.                         }
  502. #else
  503.                         newAlias = realloc(theAlias, strlen(theAlias) + strlen(str) + 1);
  504. #endif
  505.                         if (newAlias == (char *) NULL) {
  506.                             fprintf(stderr, "Can't get string buffer for alias!");
  507.                             break;
  508.                         }
  509.                         theAlias = newAlias;
  510.                         strcat(theAlias, str);
  511.                         while(strlen(theAlias) > 0 && theAlias[strlen(theAlias)-1] <= ' ') {
  512.                             theAlias[strlen(theAlias)-1] = '\0';
  513.                         }
  514.                     }
  515.                 }
  516.                 if((nargs=getargs(theAlias, args)) > 2) {
  517.                     if(strcmp(args[0], "alias") == SAME && strcmp(args[1], *argvec) == SAME) {
  518.                         gotalias = TRUE;
  519.                         for(i=2 ; i < nargs ; i++) {
  520.                             err &= sendit(argc, argv, args[i], remotes);
  521.                         }
  522. #ifdef MULTIFINDER
  523.                         DisposHandle(aliasHandle);
  524. #else
  525.                         free(theAlias);
  526. #endif
  527.                         theAlias = (char *) NULL;
  528.                         break;
  529.                     }
  530.                 }
  531.                 if (theAlias) {
  532. #ifdef MULTIFINDER
  533.                     DisposHandle(aliasHandle);
  534. #else
  535.                     free(theAlias);
  536. #endif
  537.                     theAlias = (char *) NULL;
  538.                 }
  539.             }
  540.             fclose(aliasfile);
  541.         }
  542.         if(gotalias == TRUE)
  543.             continue;
  544. #endif Upgrade
  545.         err &= sendit(argc, argv, *argvec, remotes);
  546.     }
  547.     /* dump remotes if necessary */
  548.     if ( strlen( remotes ) > 0 )
  549.         err &= sendone( argc, argv, remotes, TRUE );
  550.  
  551. #ifndef RMAIL
  552.  
  553.     if (strlen(mailcopy) > 0) {
  554.         /* wants copy of mail kept */
  555.         mkfilename( miscbuff, maildir, mailcopy );
  556.         if (*maildir != SEPCHAR)
  557.              mkfilename(mailsent, mcurdir, miscbuff);
  558.          else strcpy(mailsent, miscbuff);
  559.     
  560.         if ( debuglevel > 4 )
  561.            fprintf( stderr, "pcmail: copfile = %s\n", mailsent );
  562.         err &= sendone( argc, argv, mailsent, FALSE );
  563.     }
  564. #endif
  565.  
  566.     UNLINK( tfilename );
  567.     chdir( mcurdir );
  568.     /*
  569.     closedir(spoolDir);
  570.     */
  571.     return(err);
  572. }
  573.  
  574. /*
  575.     Get the current file-sequence number, and write out an updated one
  576. */
  577. void GetSequenceNumber()
  578. {
  579.     FILE   *tempfile;
  580.     char    miscbuff[255];
  581.     char    tfilename[255];
  582.     /* get sequence number */
  583.     mkfilename( miscbuff, confdir, SFILENAME);
  584.     if (*confdir != SEPCHAR)
  585.         /* make it an absolute pathname */
  586.         mkfilename(tfilename, mcurdir, miscbuff);
  587.     else strcpy(tfilename, miscbuff);
  588.  
  589.      if ( debuglevel > 4 )
  590.         fprintf( stderr, "pcmail: opening %s\n", tfilename ); /* */
  591.     tempfile = FOPEN( tfilename, "r", 't' );
  592.     if (tempfile != (FILE *)NULL) {
  593.         fscanf( tempfile, "%ld", &sequence );
  594.         fclose( tempfile );
  595.     }
  596.      else {
  597.          fprintf( stderr, "pcmail: can't find %s file, creating\n",
  598.                      tfilename );
  599.          sequence = 1;    /* start at 1 */
  600.      };
  601.  
  602.     /* update sequence number */
  603.     if ( debuglevel > 5 )
  604.         fprintf( stderr, "pcmail: new sequence # %ld\n", sequence );
  605.  
  606.     tempfile = FOPEN( tfilename, "w", 't' );
  607.     if (tempfile != (FILE *)NULL) {
  608.         fprintf( tempfile, "%ld\n", sequence+1 );
  609.         fclose( tempfile );
  610.     }
  611. }
  612.  
  613.  
  614. char fpat1[] = "%c.%.7s%04ld";
  615. char fpat2[] = "S %s %s %s - %s 0666 %s";
  616.  
  617.  
  618. /* sendone copies file plus headers to appropriate postbox
  619.    NB. we do headers here to allow flexibility later, for example
  620.    in being able to do bcc, per host service processing etc.
  621. */
  622. sendone(argc, argv, address, remote)
  623.     char **argv;
  624.     int argc;
  625.     char *address; {
  626.     register char     *cp;
  627.     struct tm        *timeinfo;
  628.     static char        *dw[7] = {"Sun","Mon","Tue","Wed",
  629.                               "Thu","Fri","Sat"},
  630.                     *mth[12] = {"Jan","Feb","Mar","Apr",
  631.                                 "May","Jun","Jul","Aug",
  632.                                 "Sep","Oct","Nov","Dec"};
  633.                                 
  634.     char    icfilename[32];        /* local C. copy file */
  635.     char    ixfilename[32];        /* local X. xqt file */
  636.     char    idfilename[32];        /* local D. data file */
  637.     char    rxfilename[32];        /* remote X. xqt file */
  638.     char    rdfilename[32];        /* remote D. data file */
  639.      char    tmfilename[32];        /* temporary storage */
  640. #if MSDOS
  641.      char    cixfilename[32];        /* canonical ixfilename */
  642.      char    cidfilename[32];        /* canonical idfilename */
  643. #endif
  644.     char forwardto[256];
  645.     char *wherefrom;
  646.      if ( remote ) {
  647.          /* sprintf all required file names */
  648.         sprintf( tmfilename, fpat1, 'C', viaremote, sequence );
  649.         importpath( icfilename, tmfilename );
  650. #ifdef MSDOS
  651.          sprintf( cidfilename, fpat1, 'D', viaremote, sequence );
  652.         importpath( idfilename, cidfilename );
  653.         sprintf( cixfilename, fpat1, 'D', nodename, sequence );
  654.          importpath( ixfilename, cixfilename );
  655. #else
  656.         sprintf( tmfilename, fpat1, 'D', viaremote, sequence );
  657.         importpath( idfilename, tmfilename );
  658.         sprintf( tmfilename, fpat1, 'D', nodename, sequence );
  659.         importpath( ixfilename, tmfilename );
  660. #endif
  661.         sprintf( rdfilename, fpat1, 'D', nodename, sequence );
  662.         sprintf( rxfilename, fpat1, 'X', nodename, sequence );
  663.      }
  664.      else {
  665.         /* postbox file name */
  666.          if ( index( address, SEPCHAR ) == (char *)NULL )
  667.             mkfilename( idfilename, maildir, address );
  668.         else
  669.             strcpy( idfilename, address );
  670.     }
  671.  
  672.     if ( debuglevel > 5 )
  673.          fprintf( stderr, "pcmail: sendone: %s\n", idfilename );
  674.  
  675.      if ( remote == FALSE ) {
  676.         if ( debuglevel > 5 )
  677.            fprintf( stderr, "pcmail: sendone: check for remote\n" );
  678.         /* check for forwarding */
  679.         if ( (mailfile = FOPEN( idfilename, "r", 't' )) != (FILE *)NULL ) {
  680.             cp = fgets( buf, BUFSIZ, mailfile );
  681.             fclose( mailfile );
  682.             if (cp != (char *)NULL)
  683.                 if (strncmp( buf, FORWARD, 10 ) == 0) {
  684.                     strcpy( forwardto, buf+11 );
  685.                     if (strchr(forwardto, '!') != NULL || strchr(buf, '@') != NULL) {
  686.                         return( sendone( argc, argv, forwardto, TRUE ) );
  687.                     } else {
  688.                         return( sendone( argc, argv, forwardto, FALSE ) );
  689.                     } 
  690.                 }
  691.         }
  692.     }
  693.  
  694.     /* open mailfile */
  695.     if ( (mailfile = FOPEN( idfilename, "a", remote?'b':'t' )) == (FILE *)NULL ) {
  696.         fprintf( stdout, "pcmail: cannot append to %s\n", idfilename );
  697.         return( 0 );
  698.     }
  699.  
  700.     if ( debuglevel > 5 )
  701.         fprintf( stderr, "pcmail: append to mailfile\n" );
  702.  
  703.     tloc = time( (time_t *)NULL );
  704.     thetime = ctime(&tloc);
  705.      (void)strcpy(chartime, thetime);    /* make our own copy */
  706.      thetime = chartime;    /* and work with our own copy */
  707.     thetime[strlen(thetime)-1] = '\0';
  708.     timeinfo = localtime(&tloc);
  709.     
  710. #ifdef RMAIL
  711.     tempfile = FOPEN( tfilename, "r", 't' );
  712.     if ( tempfile == (FILE *)NULL) {
  713.         fprintf( stdout, "pcmail: can't re-open %s\n", tfilename );
  714.         return( 0 );
  715.     }
  716.     fgets( buf, 512, tempfile );
  717.     if ( strncmp( buf, "From ", 5 ) == 0 ) {
  718.         sscanf(buf, "From %s ", miscbuff);
  719. /*        printf("From [%s]\n", miscbuff); */
  720.     }
  721.     if (strlen(gotitfrom) > 0) {
  722.         wherefrom = gotitfrom;
  723.     } else {
  724.         wherefrom = mailserv;
  725.     }
  726.     if (strchr(miscbuff, '@') != NULL) {
  727.         fprintf(mailfile, "From %s %s", miscbuff, thetime);
  728.     } else {
  729.         fprintf(mailfile, "From %s!%s %s", wherefrom, miscbuff, thetime );
  730.     }
  731.     fputc( '\012', mailfile );
  732.     fprintf( mailfile, "Received: from %s by %s with UUPC;", wherefrom, domain);
  733.     fputc( '\012', mailfile );
  734.     sprintf(chartime, "%3.3s, %02.2d %3.3s %02.2d %02.2d:%02.2d:%02.2d %s",
  735.                 dw[timeinfo->tm_wday],
  736.                 timeinfo->tm_mday,
  737.                 mth[timeinfo->tm_mon],
  738.                 timeinfo->tm_year,
  739.                 timeinfo->tm_hour,
  740.                 timeinfo->tm_min,
  741.                 timeinfo->tm_sec,
  742.                 timediff);
  743.     fprintf( mailfile, "          %s", thetime);
  744.     fputc( '\012', mailfile );
  745. #else /* RMAIL */
  746.     fprintf( mailfile, "From %s %s", mailbox, thetime );
  747.     if ( remote )
  748.         fprintf( mailfile, " remote from %s", nodename );
  749.     fputc( '\012', mailfile );
  750.     fprintf( mailfile, "Received: by %s (pcmail);", domain);
  751.     fputc( '\012', mailfile );
  752.     sprintf(chartime, "%3.3s, %02.2d %3.3s %02.2d %02.2d:%02.2d:%02.2d %s",
  753.                 dw[timeinfo->tm_wday],
  754.                 timeinfo->tm_mday,
  755.                 mth[timeinfo->tm_mon],
  756.                 timeinfo->tm_year,
  757.                 timeinfo->tm_hour,
  758.                 timeinfo->tm_min,
  759.                 timeinfo->tm_sec,
  760.                 timediff);
  761.     fprintf( mailfile, "          %s", thetime);
  762.     fputc( '\012', mailfile );
  763.     fprintf( mailfile, "Date: %s", thetime);
  764.     fputc( '\012', mailfile );
  765.     /* add Date:, From: and Message-ID: headers */
  766.     fprintf( mailfile, "From: %s <%s@%s>", name, mailbox, domain );
  767.     fputc( '\012', mailfile );
  768.     fprintf( mailfile, "Message-Id: <%ld@%s>", sequence, domain );
  769.     fputc( '\012', mailfile );
  770.     
  771.     /* add To: headers */
  772.     fprintf(mailfile, "To:");
  773.     while(--argc > 0)
  774.         fprintf(mailfile, " %s", *++argv);
  775.     fputc('\012', mailfile);    /* better Ken? */
  776.  
  777.     if ( strlen( Subject ) > 0 ) {
  778.         fprintf( mailfile, "Subject: %s", Subject );
  779.         fputc( '\012', mailfile );
  780.     }
  781. #ifdef PCMAIL
  782.     /* add Message-Lines: and Content-Length: headers */
  783.     fprintf( mailfile, "X-Message-Lines: %ld", lines );
  784.     fputc( '\012', mailfile );
  785.     fprintf( mailfile, "Content-Length: %ld", bytes );
  786.     fputc( '\012', mailfile );
  787. #endif /* PCMAIL */
  788.     /* copy tempfile to postbox file */
  789.     tempfile = FOPEN( tfilename, "r", 't' );
  790.     if ( tempfile == (FILE *)NULL) {
  791.         fprintf( stdout, "pcmail: can't re-open %s\n", tfilename );
  792.         return( 0 );
  793.     }
  794. #endif /* RMAIL */
  795.     if (debuglevel > 4)
  796.        fprintf( stderr, "pcmail: copy tempfile %s to %s\n",
  797.                         tfilename, idfilename );
  798.  
  799.     while (fgets( buf, 512, tempfile ) != (char *)NULL) {
  800.         if ( strncmp( buf, "From ", 5 ) == 0 )
  801.             fputc( '>', mailfile );
  802.         cp = &buf[ strlen(buf)-1 ];
  803.         if ( *cp == '\n' )
  804.             *cp = '\0';
  805.         fputs( buf, mailfile );
  806.         fputc( '\012', mailfile );
  807.      }
  808.     if (!remote) fputc( '\012', mailfile );
  809.  
  810.     /* close files */
  811.     fclose( mailfile );
  812.     fclose( tempfile );
  813.  
  814.     /* all done unless going to remote via uucp */
  815.     /* must create the job control files */
  816.     if ( remote == TRUE ) {
  817.  
  818.         /* create remote X xqt file */
  819.         mailfile = FOPEN( ixfilename, "w", 'b' );
  820.         if     (mailfile == (FILE *)NULL) {
  821.             fprintf( stdout, "pcmail: cannot append to %s\n", ixfilename );
  822.             return( 0 );
  823.         }
  824.         fprintf( mailfile, "U %s %s", uucp, nodename );
  825.         fputc( '\012', mailfile );
  826.         fprintf( mailfile, "F %s", rdfilename );
  827.         fputc( '\012', mailfile );
  828.         fprintf( mailfile, "I %s", rdfilename );
  829.         fputc( '\012', mailfile );
  830.         fixaddress(address+1);
  831.         fprintf( mailfile, "C rmail %s", address );
  832.         fputc( '\012', mailfile );
  833.         fclose( mailfile );
  834.  
  835.         /* create local C copy file */
  836.         mailfile = FOPEN( icfilename, "w", 't' );
  837.         if     (mailfile == (FILE *)NULL) {
  838.             fprintf( stdout, "pcmail: cannot append to %s\n", icfilename );
  839.             return( 0 );
  840.         }
  841.  
  842. #if MSDOS
  843.          fprintf( mailfile, fpat2, cidfilename, rdfilename,
  844.                      uucp, cidfilename, uucp );
  845.          fputc( '\012', mailfile );
  846.          fprintf( mailfile, fpat2, cixfilename, rxfilename,
  847.                      uucp, cixfilename, uucp );
  848.          fputc( '\012', mailfile );
  849. #else
  850.         fprintf( mailfile, fpat2, idfilename, rdfilename,
  851.                     uucp, idfilename, uucp );
  852.         fputc( '\012', mailfile );
  853.         fprintf( mailfile, fpat2, ixfilename, rxfilename,
  854.                     uucp, ixfilename, uucp );
  855.         fputc( '\012', mailfile );
  856. #endif
  857.         fclose( mailfile );
  858.  
  859.     } /* if ( remote == TRUE ) */
  860.  
  861.     return( 1 );
  862. }
  863.  
  864. /* Get address into percent form for rmail, and delete mailhost name */
  865. fixaddress(address)
  866. char    *address;
  867. {
  868.     char        temp[BUFSIZ];
  869.     register    char    *p, *q, *r;
  870.     
  871.     q = address;
  872.     temp[0] = '\0';
  873.     while ( (p = index(q, ' ')) != NULL ) {
  874.         *p = '\0';
  875.         fixpercent(q);
  876. #ifdef    PERCENT_ADDRS
  877.         if ((r = strrchr(q, '@')) != NULL) *r = '%';
  878.         if ((r = strrchr(q, '%')) != NULL ) {
  879.             if (strcmp(r+1, mailserv) == 0) *r = '\0';
  880.             if ((r = strrchr(q, '%')) != NULL) *r ='@';
  881.         }
  882. #else
  883.         if ((r = strchr(q, '!')) != NULL) {
  884.             if (strncmp(q, mailserv, (int)(r - q)) == 0)
  885.                 q = r + 1;
  886.         }
  887. #endif    PERCENT_ADDRS
  888.         strcat(temp, q);
  889.         strcat(temp, " ");
  890.         q = ++p;
  891.     }
  892.     /* do the last one */
  893.     fixpercent(q);
  894. #ifdef    PERCENT_ADDRS
  895.     if ((r = strrchr(q, '@')) != NULL) *r = '%';
  896.     if ((r = strrchr(q, '%')) != NULL ) {
  897.         if (strcmp(r+1, mailserv) == 0) *r = '\0';
  898.         if ((r = strrchr(q, '%')) != NULL) *r ='@';
  899.     }
  900. #else
  901.         if ((r = strchr(q, '!')) != NULL) {
  902.             if (strncmp(q, mailserv, (int)(r - q)) == 0)
  903.                 q = r + 1;
  904.         }
  905. #endif    PERCENT_ADDRS
  906.     strcat(temp, q);
  907.     strcpy(address, temp);
  908. }
  909.  
  910. #ifdef    PERCENT_ADDRS
  911. /*    converts addresses to RFC 822 percent form
  912.     %,@ takes precedence over ! e.g.,
  913.     a!b!c%y@z -> c%b%a%y@z
  914. */
  915. fixpercent(addr)
  916. char *addr;
  917. {
  918.     char    front[BUFSIZ];
  919.     register char    *p;
  920.  
  921.     if ( (p = strrchr(addr, '%')) != NULL ||
  922.          (p = strrchr(addr, '@')) != NULL) {
  923.  
  924.         *p = '\0';
  925.         if (strchr(addr, '!') != NULL) fixpercent(addr);
  926.         if (strchr(p+1, '!') != NULL) fixpercent(p+1);
  927.         *p = '%';
  928.     }
  929.     else if ( (p = strrchr(addr, '!')) != NULL) {
  930.         *p++ = '\0';
  931.         strcpy(front, p);
  932.         fixpercent(addr);
  933.         strcat(front, "%");
  934.         strcat(front, addr);
  935.         strcpy(addr, front);
  936.     }
  937. }
  938. #else
  939. /*    converts addresses to uucp ! form
  940.     %,@ takes precedence over ! e.g.,
  941.     a!b!c%y@z -> z!y!a!b!c
  942. */
  943. fixpercent(addr)
  944. char *addr;
  945. {
  946.     char    front[BUFSIZ];
  947.     register char    *p;
  948.  
  949.     if ( (p = strrchr(addr, '@')) != NULL ||
  950.          (p = strrchr(addr, '%')) != NULL) {
  951.         *p = '\0';
  952.         strcpy(front, p+1);
  953.         strcat(front, "!");
  954.         fixpercent(addr);
  955.         strcat(front, addr);
  956.         strcpy(addr, front);
  957.     }
  958. }
  959. #endif    PERCENT_ADDRS
  960.  
  961. #ifndef AMIGA
  962. #ifdef RMAIL
  963. rnews(argc, argv)
  964. int argc;
  965. char *argv[];
  966. {
  967.     struct tm    *thetm;
  968.     char    filename[132];
  969.     char    format[128];
  970.     FILE     *f;
  971.     char    buf[BUFSIZ];
  972.  
  973.     static int count = 0;
  974.     int gotBytes;
  975.  
  976.     tloc = time( (time_t *)NULL );
  977.     thetime = ctime(&tloc);
  978.     tloc = time( (time_t *)NULL );
  979.  
  980.     thetm = localtime( &tloc );
  981.  
  982.     /* mkfilename( format, spooldir, NEWSDIR );    */
  983.     sprintf( filename, NEWSDIR,
  984.         thetm->tm_year % 100, thetm->tm_mon+1,
  985.         thetm->tm_mday, thetm->tm_hour,
  986.         thetm->tm_min,  thetm->tm_sec,  count
  987.         );
  988.  
  989.     count++;
  990.  
  991.     if ( debuglevel > 5 )
  992.         fprintf( stderr, "rnews: %s\n", filename );
  993.  
  994.     if ( (f = FOPEN( filename, "w", 'b' )) == (FILE *)NULL ) {
  995.         fprintf( stderr, "rnews: can't open %s %d\n", filename, errno );
  996.         return( 0 );
  997.     }
  998.  
  999.     while ( (gotBytes = fread( buf, 1, BUFSIZ, stdin)) != 0) {
  1000.         fwrite( buf, 1, gotBytes, f );
  1001. #ifdef MULTIFINDER
  1002.         Check_Events(0);
  1003. #endif
  1004.     }
  1005.  
  1006.     fclose( f );
  1007.     return (1);
  1008. }
  1009.  
  1010. #endif /* RMAIL */
  1011. #endif /* AMIGA */
  1012.  
  1013.